﻿using System.Collections.Generic;
using System.Linq;
using HHPS.CreditEducation.DataProvider;
using HHPS.CreditEducation.Frameworks.Commons;
using HHPS.CreditEducation.Frameworks.Constants;

namespace HHPS.CreditEducation.Business
{
    public partial class Business
    {

        #region -- Get Kind of subject --

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public List<KindOfSubject> GetListKindOfSubject()
        {
            return DataContex != null ? DataContex.KindOfSubjects.ToList() : null;
        }

        #endregion

        #region Common

        private static bool KindOfSubjectCommonValidator(KindOfSubject kindOfSubject, out string message)
        {
            if (string.IsNullOrWhiteSpace(kindOfSubject.Name))
            {
                message = string.Format(ConstantMessages.RequireFieldIsBlank, "tên Loại môn học");
                return false;
            }

            if (kindOfSubject.Name.Length >= 50)
            {
                message = string.Format(ConstantMessages.FieldDataOverMaxLength, "tên Loại môn học", 50);
                return false;
            }

            message = string.Empty;
            return true;
        }

        #endregion

        #region -- Add Kind of subject --

        /// <summary>
        /// This function check validate of add a new facutly function
        /// </summary>
        /// <param name="kindOfSubject"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool AddNewKinhOfSubectValidator(KindOfSubject kindOfSubject, out string message)
        {
            if (!KindOfSubjectCommonValidator(kindOfSubject, out message)) return false;

            if (DataContex.KindOfSubjects.Any(k => k.Name.ToLower() == kindOfSubject.Name.ToLower()))
            {
                message = string.Format(ConstantMessages.ItemIsExisted, kindOfSubject.Name);
                return false;
            }

            return true;
        }

        /// <summary>
        /// This function add a new facutly into list.
        /// </summary>
        public void AddNewKindOfSubject(KindOfSubject kindOfSubject)
        {
            DataContex.KindOfSubjects.AddObject(kindOfSubject);
            DataContex.SaveChanges();
        }

        #endregion

        #region -- Edit Kind of subject --

        /// <summary>
        ///
        /// </summary>
        /// <param name="kindOfSubject"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool EditKindOfSubjectValidator(KindOfSubject kindOfSubject, out string message)
        {
            var id = kindOfSubject.Id;
            if (!DataContex.KindOfSubjects.Any(k => k.Id == id))
            {
                message = ConstantMessages.CanNotIdentifyItem;
                return false;
            }

            if (!KindOfSubjectCommonValidator(kindOfSubject, out message)) return false;

            if (DataContex.KindOfSubjects.Any(k => k.Name.ToLower() == kindOfSubject.Name.ToLower() && k.Id != id))
            {
                message = string.Format(ConstantMessages.ItemIsExisted, kindOfSubject.Name);
                return false;
            }

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="kindOfSubject"></param>
        public bool EditKindOfSubject(KindOfSubject kindOfSubject)
        {
            var id = kindOfSubject.Id;
            var updatekindOfSubject = DataContex.KindOfSubjects.SingleOrDefault(k => k.Id == id);

            if (updatekindOfSubject == null)
                return false;

            updatekindOfSubject.Name = kindOfSubject.Name;
            DataContex.SaveChanges();
            return true;
        }

        #endregion

        #region -- Delete Kind of Subject --

        /// <summary>
        /// 
        /// </summary>
        /// <param name="kindOfSubjects"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool DeleteKindOfsubjectsValidator(IEnumerable<KindOfSubject> kindOfSubjects, out string message)
        {
            const string intialize = "Loại Môn học: ";
            var itemsCannotIdentify = (from kindOfSubject in kindOfSubjects
                                       let id = kindOfSubject.Id
                                       where !DataContex.KindOfSubjects.Any(k => k.Id == id)
                                       select kindOfSubject).Aggregate(intialize, (current, kindOfSubject) => current + (kindOfSubject.Name + ", "));

            if (itemsCannotIdentify != intialize)
            {
                message = string.Format(ConstantMessages.SomeItemsCanNotIdentify, itemsCannotIdentify.TrimEnd(','));
                return false;
            }

            var itemsInUse = (from kindOfSubject in kindOfSubjects
                              let id = kindOfSubject.Id
                              where DataContex.Subjects.Any(s => s.IdKindOfSubject == id)
                              select kindOfSubject).Aggregate(intialize, (current, kindOfSubject) => current + (kindOfSubject.Name + ", "));

            if (itemsInUse != intialize)
            {
                message = string.Format(ConstantMessages.SomeItemsInUseCanNotDelete, itemsInUse.TrimEnd(','));
                return false;
            }

            message = string.Empty;
            return true;
        }

        /// <summary>
        /// Delete object
        /// </summary>
        public void DeleteKindOfSubjects(List<KindOfSubject> kindOfSubjects)
        {
            for (var i = kindOfSubjects.Count - 1; i >= 0; i--)
            {
                var id = kindOfSubjects[i].Id;
                var deleteKindOfSubject = DataContex.KindOfSubjects.Single(k => k.Id == id);
                DataContex.KindOfSubjects.DeleteObject(deleteKindOfSubject);
            }
            DataContex.SaveChanges();
        }

        #endregion
    }
}